package email

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"go-caipu/pkg/tsdb/email/models"
	"net/http"
	"time"
)

type HTTPCallbackHandler struct {
	timeout time.Duration
	client  *http.Client
}

func NewHTTPCallbackHandler() *HTTPCallbackHandler {
	return &HTTPCallbackHandler{
		timeout: 10 * time.Second,
		client: &http.Client{
			Timeout: 10 * time.Second,
		},
	}
}

func (h *HTTPCallbackHandler) OnSuccess(email *models.Email) error {
	payload := map[string]interface{}{
		"email_id": email.MessageID,
		"status":   "success",
		"time":     time.Now().Format(time.RFC3339),
		"attempts": email.Attempts,
	}

	return h.sendCallback(email.CallbackURL, payload)
}

func (h *HTTPCallbackHandler) OnFailure(email *models.Email, err error) error {
	payload := map[string]interface{}{
		"email_id": email.MessageID,
		"status":   "failed",
		"error":    err.Error(),
		"attempts": email.Attempts,
		"time":     time.Now().Format(time.RFC3339),
	}

	return h.sendCallback(email.CallbackURL, payload)
}

func (h *HTTPCallbackHandler) sendCallback(url string, payload interface{}) error {
	jsonData, err := json.Marshal(payload)
	if err != nil {
		return err
	}

	ctx, cancel := context.WithTimeout(context.Background(), h.timeout)
	defer cancel()

	req, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewBuffer(jsonData))
	if err != nil {
		return err
	}

	req.Header.Set("Content-Type", "application/json")

	resp, err := h.client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode >= 400 {
		return fmt.Errorf("callback failed with status %d", resp.StatusCode)
	}

	return nil
}
